package cn.com.dhcc.app.pub.module.codetable.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import cn.com.dhcc.app.core.base.BaseService;
import cn.com.dhcc.app.core.base.cache.CacheGroupName;
import cn.com.dhcc.app.core.base.log.LogType;
import cn.com.dhcc.app.core.base.user.AuthUserType;
import cn.com.dhcc.app.core.component.log.Log;
import cn.com.dhcc.app.core.exception.DaoException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.pub.core.CM;
import cn.com.dhcc.app.pub.core.Table;
import cn.com.dhcc.app.pub.module.codetable.dao.wapper.CodeTableWapper;
import cn.com.dhcc.app.pub.module.codetable.vo.CodeTable;
import cn.com.dhcc.app.pub.module.logmgr.vo.LogBean.LOG_TYPE;


/**
 * 码表服务
 * @日期：2013-6-25下午4:17:11
 * @作者：乔兵
 */
@Service("codeTableService")
public class CodeTableService extends BaseService{
	private static final String CODETABLE_CACHE_KEY = "_code_table_key";
	private static Logger logger = Log.getLogger(LogType.SYSINNER);
	/**
	 * 类型，所有类型在此注册
	 * @author qiao
	 * @2013-11-4 @下午7:17:50
	 */
	public static enum CODE_TYPE{//和codetable表的type内容一致
		FLOWTYPE,
		FUNDSTOCARRYOUTTHESITUATION,
		STATIONBANK,
		SWSTYPE,
		IMPLEMENTORGANIZATIONSETUP,
		MONITORINGMODEA,
		NATUREOFGROUNDWATER,
		PLANNINGUNITFOUNDATIONWORK,
		PROJECTCATEGORY,
		PROJECTUSE,
		FEASIBILITYANDEFFECTIVENESSMEASURES,
		WATERFLOWMEASUREMENTMETHOD,
		IRRIGATIONTYPES,
		MONGLEVEL,
		MAJORPOLLUTANTSPROJECT,
		MEASUREMENTMETHOD,
		MININGSTRATACATEGORY,
		MULTIMEDIACATEGORY,
		POWERCATEGORY,
		PUMPTYPE,
		QUARTER,
		WATERPRICECATEGORIES,
		WATERRESOURCESPROJECTPURCHASINGWAY,
		CONSTRUCTIONCONDITION,
		BODYTYPE,
		CLASSINFORMATIONSTORED,
		ECONOMICTYPEWATERWITHDRAWAL,
		EDUCATIONBACKGROUND,
		FEASIBILITYPLANNINGOBJECTIVES,
		FLOW,
		HYDROELECTRICORGANIZATIONLEVEL,
		RESULTTYPE,
		SEWAGETREATMENTWAY,
		SPACETYPERELATIONSHIP,
		THECONTENTSOFTHEPLAN,
		UNCONVENTIONALWATERTYPE,
		WASTEWATERDISCHARGEWAY,
		JOBLEVEL,
		OUTLETNATURE,
		OUTLETSETTYPE,
		WATERRESOURCESPROJECTLEVEL,
		WATERRESOURCESPROJECTPROPERTIES,
		WAYINTOTHERIVER,
		AREAOFGROUNDWATERMANAGEMENTSTYLE,
		CATCHWTWAY,
		EGINTTP,
		SWSCHAR,
		USEDIRECTIONFORWATERRESOURCESFEE,
		PHOTOSCENERYCATEGORY,
		PLANNINGANDTECHNICALROUTEANDMETHOD,
		PROPAGANDAANDTRAINING,
		WATERQUALITYTYPE,
		WATERTYPE,
		WEATHERCONDITIONS,
		EUTROPHICATIONDEGREE,
		EVALUATIONPERIOD,
		FORWATERUSE,
		GROUNDWATERDEPTHANNOTATION,
		HYDROPOWERSTATIONTYPE,
		RIVERBASINLEVEL,
		RURALWATERSUPPLYPROJECT,
		OVERDRAFTENVIRONMENTGEOLOGYPROBLEMS,
		PLANNINGAPPROVALSTATUS,
		POLITICALLANDSCAPE,
		PROJECTLEVEL,
		WATERLOGTYPE,
		INDUSTRYCATEGORYPART,
		NATUREOUTLET,
		APPLSTATUS,
		ENTERPRISEFORWATERTYPE,
		RESERVOIRENGINEERINGLEVEL,
		RIVERLEVEL,
		SEWAGETREATMENTPLANTCONSTRUCTIONSCALE,
		SMELLTASTELEVEL,
		IRRIGATIONAREASIZE,
		MONITORINGANDEVALUATIONPLAN,
		MONITORINGMODEB,
		PILOTSCHEME,
		PROJECTPROPERTY,
		WATERPROOFLEVELOFQUALIFICATION,
		WATERWAY,
		BASETYPE,
		CHARGEFORM,
		GROUNDWATERTYPES,
		RIVERADMINISTRATIVEBOUNDARYSECTIONLEVEL,
		TAKEWATERUSERTYPES,
		WATERDIVERSIONMODE,
		WATERINTAKEPERMITPROCESSINGTYPE,
		LOCKSCATEGORIES,
		PROJECTPROCUREMENT,
		PROJECTTYPE,
		WATERREGULATIONPROJECTCATEGORIES,
		WATERSUPPLYCONDITIONCONTINUOUSLY,
		WATERWITHDRAWALSTATIONTYPE,
		WRWFPROVALSTATUS,
		WTPERMITTYPE,
		ACHIEVEMENTLEVEL,
		AWARDTYPEANDRATING,
		DRAWDOWNFUNNELPROPERTIES,
		EVALUATIONMETHOD,
		GROUNDWATERWATERWAY,
		SEX,//性别
		STATION,
		SUBCATCHWTMTD,
		TRANSMISSIONMODE,
		WATERADMINISTRATIONDEPARTMENTS,
		IMPORTANTPROJECT,
		MEADOWTYPE,
		MEASTP,
		MEASUREMENTMETHODS,
		PERSONNELCATEGORY,
		WATERMETERMEASURINGRANGE,
		WATERPROPERTY,
		INDUSTRYCATEGORY,
		UNDERGROUNDWATERTYPE,
		BUSICODE,//业务编码
		AUTHUSERTYPE,
		LOG_TYPE,
		S_TYPE;
		private  CODE_TYPE(){
		}
	}
	/**
	 * 只在{@link cn.com.dhcc.app.pub.core.InitListener}调用
	 * @param context
	 * @throws ServiceException 
	 */
	public static void loadAllCodeTableIntoCT(boolean reLoad) throws ServiceException{
		if(reLoad){
			String sql = "SELECT *  FROM "+WSD_TABLE(Table.SYS_BASE_TABLE.SYS_CODETABLE)+" ORDER BY type,code ASC";
			Map<String, Map<String, CodeTable>> codeTableMap = new HashMap<String, Map<String,CodeTable>>();
			try {
				List<CodeTable> codeTables = CM.getDao().list("获取codetable", sql,new CodeTableWapper(),null);
				if(codeTables!=null&&!codeTables.isEmpty()){
					for (Iterator<CodeTable> iterator = codeTables.iterator(); iterator
							.hasNext();) {
						CodeTable codeTable = (CodeTable) iterator.next();
						String type = codeTable.getType();
						Map<String, CodeTable> ct = codeTableMap.get(type);
						if(ct==null){
							ct = new HashMap<String, CodeTable>();
							codeTableMap.put(type, ct);
						}
						ct.put(codeTable.getCode(),codeTable);
					}
					putCoteTableIntoCache(codeTableMap);
				}
			} catch (DaoException e) {
				logger.info("初始化码表失败...");
				throw new ServiceException(e);
			}
			//加入自定义码
			injectCustomCodeTable(codeTableMap);
			logger.info("初始化码表成功...");
		}
	}	
	private static void injectCustomCodeTable(Map<String, Map<String, CodeTable>> codeTableMap) {
		//OPENCLOSE
		//FILETYPE
		//YESNO
		//SUCCESSFAIL
		//用户类型
		AuthUserType[] logUserType = AuthUserType.values();
		Map<String, CodeTable> logUserMap = new HashMap<String, CodeTable>();
		codeTableMap.put("AUTHUSERTYPE", logUserMap);
		for (int i = 0; i < logUserType.length; i++) {
			String code = logUserType[i].getCode();
			String name = logUserType[i].getName();
			CodeTable codeTable = new CodeTable();
			codeTable.setCode(code);
			codeTable.setName(name);
			logUserMap.put(logUserType[i].getCode(), codeTable);
		}
				
		//log_type
		LOG_TYPE[] logType = LOG_TYPE.values();
		Map<String, CodeTable> logTypeMap = new HashMap<String, CodeTable>();
		codeTableMap.put("LOG_TYPE", logTypeMap);
		for (int i = 0; i < logType.length; i++) {
			String code = logType[i].getCode();
			String name = logType[i].getName();
			CodeTable codeTable = new CodeTable();
			codeTable.setCode(code);
			codeTable.setName(name);
			logTypeMap.put(logType[i].getCode(), codeTable);
		}
		
	}
	/**
	 * 根据类型获取某一类型的码表，key：code 
	 * @param type 
	 * @return
	 */
	public static Map<String, CodeTable> getCodeTableByType(CODE_TYPE type){
		Map<String, Map<String, CodeTable>> codeTables = getAllCodeTableFromCache();
		if(codeTables!=null&&!codeTables.isEmpty()){
			return codeTables.get(type.name());
		}
		return null;
	}
	/**
	 * 根据类型获取某一类型的码表列表
	 * @param type
	 * @return
	 */
	public static List<CodeTable> getCodeTableBeanByType(CODE_TYPE type){
		final Map<String, CodeTable> ct = getCodeTableByType(type);
		if(ct!=null&&!ct.isEmpty()){
			return new ArrayList<CodeTable>(){
			private static final long serialVersionUID = 1L;
			{
				addAll(ct.values());
			}};
		}
		return null;
	}
	/**
	 * 根据类型获取某一类型的码表code-name
	 * @param type
	 * @return
	 */
	public static Map<String, String> getCodeTableKeyValueByType(CODE_TYPE type){
		final Map<String, CodeTable> ct = getCodeTableByType(type);
		if(ct!=null&&!ct.isEmpty()){
			Map<String, String> kv = new HashMap<String, String>();
			for (Iterator<String> iterator = ct.keySet().iterator(); iterator.hasNext();) {
				String code = (String) iterator.next();
				kv.put(code, ct.get(code).getName());
			}
			return kv;
		}
		return null;
	}
	/**
	 * 根据类型和code获取某码表记录 
	 * @param type
	 * @param code
	 * @return
	 */
	public static CodeTable getCodeTable(CODE_TYPE type,String code){
		Map<String, CodeTable> ct = getCodeTableByType(type);
		if(ct!=null&&!ct.isEmpty()){
			return ct.get(code);
		}
		return null;
	}
	/**
	 * 根据code获取name
	 * @param type
	 * @param code
	 * @return
	 */
	public static String getCodeName(CODE_TYPE type,String code){
		CodeTable codeTable = getCodeTable(type, code);
		if(codeTable!=null){
			return codeTable.getName();
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	private static Map<String, Map<String, CodeTable>>  getAllCodeTableFromCache(){
		return (Map<String, Map<String, CodeTable>>) CM.getCacheService().getFromCacheByKey(CacheGroupName.CODETABLE_CACHE,"从缓存中获取codetable数据", CODETABLE_CACHE_KEY);
	}
	private static void putCoteTableIntoCache(Map<String, Map<String, CodeTable>> map){
		CM.getCacheService().insertIntoCache(CacheGroupName.CODETABLE_CACHE,"从缓存中获取codetable数据", CODETABLE_CACHE_KEY,map);
	}
	
}
